package com.ruihu.admin.module.system.datascope.service;

import com.google.common.collect.Lists;
import com.ruihu.admin.module.system.datascope.dao.DataScopeRoleDao;
import com.ruihu.admin.module.system.datascope.constant.DataScopeTypeEnum;
import com.ruihu.admin.module.system.datascope.constant.DataScopeViewTypeEnum;
import com.ruihu.admin.module.system.datascope.domain.entity.DataScopeRoleEntity;
import com.ruihu.admin.module.system.department.DepartmentTreeService;
import com.ruihu.admin.module.system.privilege.service.PrivilegeUserService;
import com.ruihu.admin.module.system.user.dao.UserDao;
import com.ruihu.admin.module.system.user.domain.dto.UserDTO;
import com.ruihu.admin.module.system.user.domain.entity.UserEntity;
import com.ruihu.admin.module.system.user.domain.vo.UserVO;
import com.ruihu.admin.module.system.role.roleuser.dao.RoleUserDao;
import com.ruihu.admin.util.BaseEnumUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * [  ]
 *
 * @author yandanyang
 * @version 1.0
 * @company Ruihu (Nanjing) Information Technology Co., Ltd
 * @copyright (c) 2018 Ruihu (Nanjing) Information Technology Co., LtdInc. All rights reserved.
 * @date 2019/4/28 0028 下午 15:56
 * @since JDK1.8
 */
@Service
public class DataScopeViewService {

    @Autowired
    private RoleUserDao roleUserDao;

    @Autowired
    private DataScopeRoleDao dataScopeRoleDao;

    @Autowired
    private DepartmentTreeService departmentTreeService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private PrivilegeUserService privilegeUserService;

    /**
     * 获取某人可以查看的所有人员信息
     *
     * @param dataScopeTypeEnum
     * @param userId
     * @return
     */
    public List<Long> getCanViewUserId(DataScopeTypeEnum dataScopeTypeEnum, Long userId) {
        DataScopeViewTypeEnum viewType = this.getUserDataScopeViewType(dataScopeTypeEnum, userId);
        if (DataScopeViewTypeEnum.ME == viewType) {
            return this.getMeUserIdList(userId);
        }
        if (DataScopeViewTypeEnum.DEPARTMENT == viewType) {
            return this.getDepartmentUserIdList(userId);
        }
        if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB == viewType) {
            return this.getDepartmentAndSubUserIdList(userId);
        }
        return Lists.newArrayList();
    }

    /**
     * 获取某人可以查看的所有部门信息
     *
     * @param dataScopeTypeEnum
     * @param UserId
     * @return
     */
    public List<Long> getCanViewDepartmentId(DataScopeTypeEnum dataScopeTypeEnum, Long UserId) {
        DataScopeViewTypeEnum viewType = this.getUserDataScopeViewType(dataScopeTypeEnum, UserId);
        if (DataScopeViewTypeEnum.ME == viewType) {
            return this.getMeDepartmentIdList(UserId);
        }
        if (DataScopeViewTypeEnum.DEPARTMENT == viewType) {
            return this.getMeDepartmentIdList(UserId);
        }
        if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB == viewType) {
            return this.getDepartmentAndSubIdList(UserId);
        }
        return Lists.newArrayList();
    }

    private List<Long> getMeDepartmentIdList(Long UserId) {
        UserEntity userEntity = userDao.selectById(UserId);
        return Lists.newArrayList(userEntity.getDepartmentId());
    }

    private List<Long> getDepartmentAndSubIdList(Long UserId) {
        UserEntity userEntity = userDao.selectById(UserId);
        List<Long> allDepartmentIds = Lists.newArrayList();
        departmentTreeService.buildIdList(userEntity.getDepartmentId(), allDepartmentIds);
        return allDepartmentIds;
    }

    /**
     * 根据员工id 获取各数据范围最大的可见范围 map<dataScopeType,viewType></>
     *
     * @param UserId
     * @return
     */
    public DataScopeViewTypeEnum getUserDataScopeViewType(DataScopeTypeEnum dataScopeTypeEnum, Long UserId) {
        if (UserId == null) {
            return DataScopeViewTypeEnum.ME;
        }

        if (privilegeUserService.isSuperman(UserId)) {
            return DataScopeViewTypeEnum.ALL;
        }
        List<Long> roleIdList = roleUserDao.selectRoleIdByUserId(UserId);
        //未设置角色 默认本人
        if (CollectionUtils.isEmpty(roleIdList)) {
            return DataScopeViewTypeEnum.ME;
        }
        //未设置角色数据范围 默认本人
        List<DataScopeRoleEntity> dataScopeRoleList = dataScopeRoleDao.listByRoleIdList(roleIdList);
        if (CollectionUtils.isEmpty(dataScopeRoleList)) {
            return DataScopeViewTypeEnum.ME;
        }
        Map<Integer, List<DataScopeRoleEntity>> listMap = dataScopeRoleList.stream().collect(Collectors.groupingBy(DataScopeRoleEntity::getDataScopeType));
        List<DataScopeRoleEntity> viewLevelList = listMap.get(dataScopeTypeEnum.getValue());
        DataScopeRoleEntity maxLevel = viewLevelList.stream().max(Comparator.comparing(e -> BaseEnumUtil.getEnumByValue(e.getViewType(), DataScopeViewTypeEnum.class).getLevel())).get();
        return BaseEnumUtil.getEnumByValue(maxLevel.getViewType(), DataScopeViewTypeEnum.class);
    }

    /**
     * 获取本人相关 可查看员工id
     *
     * @param UserId
     * @return
     */
    private List<Long> getMeUserIdList(Long UserId) {
        return Lists.newArrayList(UserId);
    }

    /**
     * 获取本部门相关 可查看员工id
     *
     * @param UserId
     * @return
     */
    private List<Long> getDepartmentUserIdList(Long UserId) {
        UserEntity userEntity = userDao.selectById(UserId);
        List<UserVO> UserList = userDao.getUserIdByDeptId(userEntity.getDepartmentId());
        List<Long> UserIdList = UserList.stream().map(e -> e.getId()).collect(Collectors.toList());
        return UserIdList;
    }

    /**
     * 获取本部门及下属子部门相关 可查看员工id
     *
     * @param UserId
     * @return
     */
    private List<Long> getDepartmentAndSubUserIdList(Long UserId) {
        UserEntity userEntity = userDao.selectById(UserId);
        List<Long> allDepartmentIds = Lists.newArrayList();
        departmentTreeService.buildIdList(userEntity.getDepartmentId(), allDepartmentIds);
        List<UserDTO> UserList = userDao.getUserIdByDeptIds(allDepartmentIds);
        List<Long> UserIdList = UserList.stream().map(e -> e.getId()).collect(Collectors.toList());
        return UserIdList;
    }

}
